package com.ihr360.payroll.service.salaryfield.impl;

import com.google.common.collect.Lists;
import com.ihr360.authority.sharing.annonation.AccessControl;
import com.ihr360.commons.exception.Ihr360Exception;
import com.ihr360.commons.lang.CollectionUtils;
import com.ihr360.commons.model.type.FieldSource;
import com.ihr360.commons.model.type.SalaryFieldValueType;
import com.ihr360.payroll.config.FieldSourcesEntity;
import com.ihr360.payroll.config.SalaryFieldTypeEntity;
import com.ihr360.payroll.config.SystemSalaryFieldValueEntity;
import com.ihr360.payroll.config.system.SystemSalaryFieldEntity;
import com.ihr360.payroll.dao.SalaryFieldTypeRepository;
import com.ihr360.payroll.model.dto.salary.basecode.SalaryFieldType;
import com.ihr360.payroll.model.dto.salary.meta.SalaryField;
import com.ihr360.payroll.service.payroll.convertor.SalaryFieldTypeConvertor;
import com.ihr360.payroll.service.salaryfield.SalaryFieldService;
import com.ihr360.payroll.service.salaryfield.SalaryFieldTypeService;
import com.ihr360.payroll.service.salaryfield.SystemSalaryFieldService;
import com.ihr360.rest.reposity.SimpleRestReposity;
import com.ihr360.rest.service.AbstractSimpleRestServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * @author richey
 */
@Service
@AccessControl(disableAll = true)
public class SalaryFieldTypeServiceImpl extends AbstractSimpleRestServiceImpl<SalaryFieldType, Long> implements SalaryFieldTypeService {

    @Autowired
    private SalaryFieldTypeRepository salaryFieldTypeRepository;

    @Autowired
    private SalaryFieldTypeConvertor salaryFieldTypeConvertor;

    @Autowired
    private SystemSalaryFieldService systemSalaryFieldService;

    @Autowired
    private SalaryFieldService salaryFieldService;

    //统计项薪资字段类型code
    private static final String COUNT_CODE = "statistics";

    @Override
    public SimpleRestReposity<SalaryFieldType, Long> getSimpleRestReposity() {
        return salaryFieldTypeRepository;
    }

    @Override
    public List<SalaryFieldTypeEntity> listAll() {
        List<SalaryFieldType> salaryFieldTypes = (List<SalaryFieldType>) salaryFieldTypeRepository.findAll();
        if (CollectionUtils.isEmpty(salaryFieldTypes)) {
            return Lists.newArrayList();
        }
        List<SalaryFieldTypeEntity> salaryFieldTypeEntities = Lists.newArrayListWithCapacity(salaryFieldTypes.size());
        salaryFieldTypes.forEach(salaryFieldType -> {
            SalaryFieldTypeEntity entity = salaryFieldTypeConvertor.convertDtoToEntity(salaryFieldType);
            salaryFieldTypeEntities.add(entity);
        });

        return salaryFieldTypeEntities;
    }

    @Override
    public SalaryFieldType queryFieldType(Long id) {
        return salaryFieldTypeRepository.findById(id);
    }

    @Override
    @Transactional
    public void save(SalaryFieldType salaryFieldType) {
        checkIndexNo(salaryFieldType);
        //新增
        Long id = salaryFieldType.getId();
        if (id == null) {
            //新增统计项字段
            if (salaryFieldType.isGenTypeTotalField()) {
                SystemSalaryFieldEntity entity = getDefaultSystemField(salaryFieldType);
                systemSalaryFieldService.saveOrUpdate(entity);
            }
        } else {
            SystemSalaryFieldEntity entity = systemSalaryFieldService.findByCode(salaryFieldType.totalCode());
            if (salaryFieldType.isGenTypeTotalField()) {//统计项
                if (entity == null) {//不存在统计项字段时,新增统计项字段
                    SystemSalaryFieldEntity entity1 = getDefaultSystemField(salaryFieldType);
                    systemSalaryFieldService.saveOrUpdate(entity1);
                }
            } else {//非统计项
                if (entity != null) {//存在统计项记录的,删除统计项字段
                    List<SalaryField> salaryFieldList = salaryFieldService.querySystemFieldType(entity.getId());
                    if (CollectionUtils.isNotEmpty(salaryFieldList)) {
                        throw new Ihr360Exception(null,"该统计项字段已被使用，无法修改统计项类型");
                    } else {
                        systemSalaryFieldService.deleteById(entity.getId());
                    }
                }
            }
        }
        salaryFieldTypeRepository.save(salaryFieldType);
    }

    private void checkIndexNo(SalaryFieldType salaryFieldType) {
        SalaryFieldType existFieldType = salaryFieldTypeRepository.findByIndexno(salaryFieldType.getIndexno());
        if (salaryFieldType.getId() == null) {
            if (existFieldType != null) {
                throw new Ihr360Exception(null,"该序列号已存在");
            }
        } else {
            if (existFieldType != null && !existFieldType.getId().equals(salaryFieldType.getId())) {
                throw new Ihr360Exception(null,"该序列号已存在");
            }
        }
    }

    private SystemSalaryFieldEntity getDefaultSystemField(SalaryFieldType salaryFieldType) {
        //统计项字段
        SalaryFieldType countField = salaryFieldTypeRepository.findByCode(COUNT_CODE);
        if (countField == null) {
            throw new Ihr360Exception(null,"统计项薪资字段类型不存在");
        }
        List<SystemSalaryFieldEntity> list = systemSalaryFieldService.listByCategory(countField.getCategory().getId());
        int index = 0;
        for (SystemSalaryFieldEntity salaryFieldEntity:list) {
            if(salaryFieldEntity.getTypeIndex() > index) {
                index = salaryFieldEntity.getTypeIndex();
            }
        }
        index++;
        SystemSalaryFieldEntity entity = new SystemSalaryFieldEntity();
        entity.setCode(salaryFieldType.totalCode());
        entity.setName(salaryFieldType.getName() + "合计");
        SalaryFieldTypeEntity salaryFieldTypeEntity = new SalaryFieldTypeEntity();
        BeanUtils.copyProperties(countField,salaryFieldTypeEntity);
        entity.setType(salaryFieldTypeEntity);
        entity.setTypeIndex(index);
        SystemSalaryFieldValueEntity valueEntity = new SystemSalaryFieldValueEntity();
        valueEntity.setDefaultSource(FieldSource.FUNCTION);
        FieldSourcesEntity sourcesEntity = new FieldSourcesEntity();
        sourcesEntity.setData(Lists.newArrayList(FieldSource.FUNCTION));
        valueEntity.setSources(sourcesEntity);
        valueEntity.setPattern(2);
        valueEntity.setValueType(SalaryFieldValueType.NUMBER);
        valueEntity.setMinValue(-99999999999999L);
        valueEntity.setMaxValue(999999999999999L);
        entity.setValueMeta(valueEntity);
        return entity;
    }
}
